<?php

/**
 * ecshop ERP v1.0
 * ----------------------------------------------------------------------------
 * http://www.phpally.com
 * Jacklee的博客 致力于php技术
 * ----------------------------------------------------------------------------
 * 作者: Jacklee
 * 邮箱: jack349392900@gmail.com
 * 创建时间: 2013-11-18
 * 最后修改时间: 2013-11-18
 */
 
/**
 * PHP文件加密和解密类
 * 尚未解决的问题：
 * 1，回调函数作参数的函数列表：
 * array_diff_uassoc，array_diff_ukey，
 * array_filter，array_intersect_uassoc，array_intersect_ukey，array_map，
 * array_reduce，array_udiff_assoc，array_udiff_uassoc，array_udiff，
 * array_uintersect_assoc，array_uintersect_uassoc，array_uintersect，
 * array_walk_recursive，array_walk，uasort，uksort，usort
 * 
 */

require_once(dirname(__FILE__) . '/cls_file.php');
require_once(dirname(__FILE__) . '/cls_array.php');
require_once(dirname(__FILE__) . '/cls_variable.php');

class cls_php_file extends cls_file{

	/*
	 * 不替换的系统保留变量名
	 */
	private $ignore_variables=array
	(
		'$_COOKIE','$_ENV','$_FILES','$_GET','$_POST',
		'$_REQUEST','$_SERVER','$_SESSION','$GLOBALS',
		'$HTTP_COOKIE_VARS','$HTTP_ENV_VARS','$HTTP_GET_VARS',
		'$HTTP_POST_FILES','$HTTP_POST_VARS','$HTTP_SERVER_VARS',
		'$HTTP_SESSION_VARS','$this'
	);
	
	/*
	 * 不替换的系统保留类函数
	 * 系统保留的普通函数也是不替换的，这个用function_exists进行判断
	 */
	private $ignore_functions=array
	(
		'__construct','__destruct','__autoload',
		'__call','__clone','__get',
		'__isset','__set','__set_state',
		'__sleep','__toString','__unset',
		'__wakeup',
		'select'//select函数名可能与mysql的sql语句select()语句冲突，例如$sql="select (a.qty*a.price) as amount from ..."
	);

	/*
	 * 不替换的类保留字
	 */
	//private $ignore_class_names=array
	//(
	//	'parent','self'
	//);	
	
	/*
	 * 带有回掉函数作参数的函数
	 */
	private $callbacks=array(
		'array_diff_uassoc','array_diff_ukey',' array_filter',
		'array_intersect_uassoc','array_intersect_ukey','array_map',
		'array_reduce','array_udiff_assoc','array_udiff_uassoc',
		'array_udiff','array_uintersect_assoc','array_uintersect_uassoc',
		'array_uintersect','array_walk_recursive','array_walk','uasort',
		'uksort','usort',
		'register_shutdown_function','session_set_save_handler','set_error_handler'
	);
	
	private $callback_functions=array();
	private $full_callback_functions=array();
	
	private $path='';
	private $files='';
	private $sub_path='encrypted/';
	
	public $variables=array();
	public $functions=array();
	public $class_names=array();
	
	public $variables_key=array();
	public $functions_key=array();
	public $class_names_key=array();

	private $file_ext='php';
	
	private $variable_key_lenth=8;
	private $function_key_lenth=8;
	private $class_name_key_lenth=8;
	
	private $cls_array;
	private $cls_variable;
	
	private $ignore_pathes=array();
	private $ignore_files=array();
	
	public function cls_php_file()
	{
		$this->cls_array=new cls_array();
		$this->cls_variable=new cls_variable();
	}
	
	public function __construct()
	{
		$this->cls_php_file();
	}
	
	/*
	public function trim_comments($content)
	{
		$comments=$this->get_comments($content);
		if(!empty($comments))
		{
			foreach($comments as $comment)
			{
				$content=str_replace($comment,'',$content);
			}
		}
		return $content;
	} 
	*/	

	public function is_comment($array)
	{
		$content=implode('',$array);
		
		$pattern1='/^\/\*(\r\n|.)*\*\/$/';
		
		$pattern2='/^\/\/.*(\r\n)$/';
		
		if(preg_match($pattern1,$content) || preg_match($pattern2,$content))
		{
			return true;
		}
		else {
			return false;
		}	
	}
	

	public function get_comments($content)
	{

		$dbl_quote_stack=array();//双引号堆栈,编号1
		$single_quote_stack=array();//单引号堆栈，编号2
		$comment_stack=array();// /****/注释堆栈，编号3
		
		$stack_switch=0;//初始化当前堆栈序号
		
		$comments=array();

		$contents=$this->split_string($content);
		
		foreach($contents as $key=>$char)
		{	
			if($char!='"' && $char!="'" && $char!='/')
			{
				if($stack_switch==3)
				{
					array_push($comment_stack,$char);
					if($this->is_comment($comment_stack))
					{
						$comments[]=implode('',$comment_stack);
						$comment_stack=array();
						$stack_switch=0;
					}
				}								
			}
			elseif($char=="/")
			{
				$next_char=$contents[$key+1];
				
				if($next_char!='/' && $next_char!='*')
				{
					array_push($comment_stack,$char);
					if($this->is_comment($comment_stack))
					{
						$comments[]=implode('',$comment_stack);
						$comment_stack=array();
						$stack_switch=0;
					}
					else{
						$tmp=implode('',$comment_stack);
						
						if(!preg_match('/^\/\/.*/',$tmp) && !preg_match('/^\/\*.*/',$tmp))
						{
							$comment_stack=array();
							$stack_switch=0;							
						}
						else{
							
						}
					}
				}
				else
				{
					if($stack_switch==3 || $stack_switch==0)
					{
						array_push($comment_stack,$char);
						
						if($this->is_comment($comment_stack))
						{
							$comments[]=implode('',$comment_stack);
							$comment_stack=array();
							$stack_switch=0;
						}
						else{
							$stack_switch=3;
						}
					}			
				}
							
			}					
			elseif($char=='"')//如果是双引号
			{
				if($stack_switch==1 || $stack_switch==0)
				{
					if(empty($dbl_quote_stack))//双引号堆栈是空的
					{
						array_push($dbl_quote_stack,$char);
						$stack_switch=1;	
					}
					else{//双引号堆栈不空
						$dbl_quote_stack=array();
						$stack_switch=0;	
					}				
				}
				elseif($stack_switch==2)
				{
					array_push($single_quote_stack,$char);
				}
				elseif($stack_switch==3)
				{
					array_push($comment_stack,$char);
				}
										
			}
			elseif($char=="'")//如果是单引号
			{
				if($stack_switch==2 || $stack_switch==0)
				{
					if(empty($single_quote_stack))//双引号堆栈是空的
					{
						array_push($single_quote_stack,$char);
						$stack_switch=2;	
					}
					else{//双引号堆栈不空
						$single_quote_stack=array();
						$stack_switch=0;	
					}				
				}
				elseif($stack_switch==1)
				{
					array_push($dbl_quote_stack,$char);
				}
				elseif($stack_switch==3)
				{
					array_push($comment_stack,$char);
				}
							
			}
			
		}
		
		return $comments;
	}	

	
	
	/*
	 * 去除php文件里的所有注释
	 */
	public function trim_comments($content)
	{		
		//替换双引号；
	    //$pattern='/"((\r\n|.)*)"/U';
	    
		$pattern='/".*((\/\/)|(\/\*.*\*\/)).*"/U';
		preg_match_all($pattern,$content,$match);
		$dbl_quote=$match[0];

		if(!empty($dbl_quote))
		{
			foreach($dbl_quote as $key=>$item)
			{
				$dbl_old_replace[]=$this->add_slash_for_slash($item);
				$dbl_patterns[]='/'.$this->add_slash_for_pattern($item).'/';
				$dbl_replacements[]='<!-dbl-'.$key.'-dbl-!>';
			}		
			if(!empty($dbl_patterns))
			{
				$content=preg_replace($dbl_patterns, $dbl_replacements, $content,1);			
			}	
		}	

		//替换单引号；
		$pattern="/'.*((\/\/)|(\/\*.*\*\/)).*'/U";
		preg_match_all($pattern,$content,$match);
	
		$single_quote=$match[0];

		if(!empty($single_quote))
		{
			foreach($single_quote as $key=>$item)
			{
				$single_old_replace[]=$this->add_slash_for_slash($item);
				$single_patterns[]='/'.$this->add_slash_for_pattern($item).'/';
				$single_replacements[]='<!-single-'.$key.'-single-!>';
			}
			
			if(!empty($single_patterns))
			{
				$content=preg_replace($single_patterns, $single_replacements, $content,1);
			}
		}
		
		//去除/**/注释
		$pattern='/\/\*(\r\n|.|\\|\/)*\*\//U';
		$content=preg_replace($pattern,'',$content);		
		
		//去除//注释
		$pattern='/\/\/(.|\\|\/)*/';
		$content=preg_replace($pattern, '', $content);	

		//去除所有空格和回车
		//$pattern='/(\s|\r\n)+/';
		//$pattern='/(\r\n)+/';
		//$content=preg_replace($pattern, ' ', $content);

		//把单引号和双引号标记替换回去
		$dbl_replacements=array();
		$single_replacements=array();
		if(!empty($dbl_quote))
		{
			foreach($dbl_quote as $key=>$item)
			{
				$dbl_replacements[]='/<!-dbl-'.$key.'-dbl-!>/';
			}
			
			if(!empty($dbl_replacements))
			{
				$content=preg_replace($dbl_replacements, $dbl_old_replace, $content,1);
			}	
		}
		
		if(!empty($single_quote))
		{
			foreach($single_quote as $key=>$item)
			{
				$single_replacements[]='/<!-single-'.$key.'-single-!>/';
			}
			if(!empty($single_replacements))
			{
				$content=preg_replace($single_replacements, $single_old_replace, $content,1);
			}	
		}	
		
		return $content;
	}	
	
	
	/*
	 * 去除php文件里的所有空格（非引号里的）和 回车
	 */
	public function trim_blank($content)
	{		
		//替换双引号；
		$pattern='/"((\r\n|.)*)"/U';
		preg_match_all($pattern,$content,$match);
	
		$dbl_quote=$match[0];
		
		if(!empty($dbl_quote))
		{
			foreach($dbl_quote as $key=>$item)
			{
				$dbl_old_replace[]=$item;
				$dbl_patterns[]='/'.$this->add_slash_for_pattern($item).'/';
				$dbl_replacements[]='<!-dbl-'.$key.'-dbl-!>';
			}

			if(!empty($dbl_patterns))
			{
				$content=preg_replace($dbl_patterns, $dbl_replacements, $content,1);
			}	
		}
		

		//替换单引号；
		$pattern="/'((\r\n|.)*)'/U";
		preg_match_all($pattern,$content,$match);
	
		$single_quote=$match[0];

		if(!empty($single_quote))
		{
			foreach($single_quote as $key=>$item)
			{
				$single_old_replace[]=$item;
				$single_patterns[]='/'.$this->add_slash_for_pattern($item).'/';
				$single_replacements[]='<!-single-'.$key.'-single-!>';
			}
			
			if(!empty($single_patterns))
			{
				$content=preg_replace($single_patterns, $single_replacements, $content,1);
			}
		}
		
		//去除所有空格和回车
		$pattern='/(\s)+/';
		$content=preg_replace($pattern, ' ', $content);
		$pattern='/(\r\n)+/';
		$content=preg_replace($pattern, ' ', $content);

		//把单引号和双引号标记替换回去
		$dbl_replacements=array();
		$single_replacements=array();
		if(!empty($dbl_quote))
		{
			foreach($dbl_quote as $key=>$item)
			{
				$dbl_replacements[]='/<!-dbl-'.$key.'-dbl-!>/';
			}
			
			if(!empty($dbl_replacements))
			{
				$content=preg_replace($dbl_replacements, $dbl_old_replace, $content,1);
			}	
		}
		if(!empty($single_quote))
		{
			foreach($single_quote as $key=>$item)
			{
				$single_replacements[]='/<!-single-'.$key.'-single-!>/';
			}
			
			if(!empty($single_replacements))
			{
				$content=preg_replace($single_replacements, $single_old_replace, $content,1);
			}	
		}
		
		
		return $content;
	}
	
	/**
	 * 正则符号转义
	 */
	private function add_slash_for_pattern($var)
	{
		$tmp=$this->split_string($var);
		if(!empty($tmp))
		{
			foreach($tmp as $key=>$item)
			{
				if($item=='/')
				{
					$tmp[$key]='\/';
				}
				elseif($item=='\\')
				{
					$tmp[$key]='\\\\';
				}
				elseif($item==')')
				{
					$tmp[$key]='\)';
				}
				elseif($item=='(')
				{
					$tmp[$key]='\(';
				}	
				elseif($item=='[')
				{
					$tmp[$key]='\[';
				}
				elseif($item==']')
				{
					$tmp[$key]='\]';
				}
				/*
				elseif($item=='<')
				{
					$tmp[$key]='\<';
				}
				elseif($item=='>')
				{
					$tmp[$key]='\>]';
				}
				*/				
				elseif($item=='{')
				{
					$tmp[$key]='\{';
				}
				elseif($item=='}')
				{
					$tmp[$key]='\}';
				}						
				elseif($item=='^')
				{
					$tmp[$key]='\^';
				}
				elseif($item=='$')
				{
					$tmp[$key]='\$';
				}
				elseif($item=='*')
				{
					$tmp[$key]='\*';
				}
				elseif($item=='|')
				{
					$tmp[$key]='\|';
				}
				elseif($item=='+')
				{
					$tmp[$key]='\+';
				}
				elseif($item=='?')
				{
					$tmp[$key]='\?';
				}
				elseif($item=='?')
				{
					$tmp[$key]='\?';
				}
				elseif($item=='.')
				{
					$tmp[$key]='\.';
				}
				elseif($item=='-')
				{
					$tmp[$key]='\-';
				}																																																				
			}
		}
		
		return implode('',$tmp);
	}
	
	public function add_slash_for_slash($var)
	{
		$tmp=$this->split_string($var);
		if(!empty($tmp))
		{
			foreach($tmp as $key=>$item)
			{
				if($item=='\\')
				{
					$tmp[$key]='\\\\';
				}																																																	
			}
		}
		return implode('',$tmp);		
	}
	

	
	/*
	 *  获得类名
	 * 	class a{} --->type1
	 *  class a extends b{} --->type2
	 *  
	 *  class a implements b{} --->type3
	 *  class a implements b,c{}--->type3
	 *  
	 *  interface a{} --->type4
	 *  interface a extends b,c{}--->type5
	 *  
	 *  class a extends b implements c,d{}--->type6
	 */
	public function get_class_names($content,$trim_repeat=true)
	{
		$pattern='/';
		$pattern.='(class\s+[a-z_A-Z0-9]+(\s|\r\n)*\{)';//--->type1
		$pattern.='|(class\s+[a-z_A-Z0-9]+\s+extends\s+[a-z_A-Z0-9]+(\s|\r\n)*\{)';//--->type2
		$pattern.='|(class\s+[a-z_A-Z0-9]+\s+implements\s+([a-z_A-Z0-9,\s])+(\s|\r\n)*\{)';//--->type3
		$pattern.='|(interface\s+[a-z_A-Z0-9]+(\s|\r\n)*\{)';//--->type4
		$pattern.='|(interface\s+[a-z_A-Z0-9]+\s+extends\s+([a-z_A-Z0-9,\s])+(\s|\r\n)*\{)';//--->type5
		$pattern.='|(class\s+[a-z_A-Z0-9]+\s+extends\s+([a-z_A-Z0-9])+\s+implements\s+([a-z_A-Z0-9,\s])+(\s|\r\n)*\{)';//--->type6
		$pattern.='/';
		
		preg_match_all($pattern,$content,$match);
		$result=$match[0];	

		if(!empty($result))
		{
			$pattern='/(class)|(interface)|(extends)|(implements)|(,)|(\r\n)|(\{)/';
			foreach($result as $key=>$class)
			{
				$classes[]=trim(preg_replace($pattern,' ',$class));
			}
			
			if(!empty($classes))
			{
				foreach($classes as $key=>$class)
				{
					$result[$key]=$this->cls_array->trim_empty(explode(' ',$class));
				}
				$result=$this->cls_array->flat_array($result);
			}
			$result=$this->cls_array->trim_repeat($result);
			
			foreach($result as $key=>$item)
			{
				$result[$key]=strtolower($item);//换为小写
			}
		}		
		
		return $result;
	}
	
	/**
	 * 获得所有类名（不重复）
	 */
	public function get_all_class_names($path='',$ignore=false)
	{
		if($ignore===false)
		{
			if(empty($path))
			{
				$files=$this->files;
			}
			else{
				$files=$this->get_files($path);
			}
		}
		else{
			$files=parent::get_files($path,$this->file_ext);
			if(!empty($files))	
			{
				foreach($files as $key=>$file)
				{
					if(!in_array($file,$this->ignore_files))
					{
						array_push($this->ignore_files,$file);
					}
				}
			}
		}		
		
		if(!empty($files))
		{
			foreach($files as $file)
			{
				$content=$this->read_file(dirname($file),basename($file));
				$class_names[]=$this->get_class_names($content);
			}
			$class_names=$this->cls_array->flat_array($class_names);
			$class_names=$this->cls_array->trim_repeat($class_names);
			$class_names=$this->cls_array->trim_empty($class_names);
		}
		else{
			$class_names=array();
		}
		
		if($ignore===true)
		{
			if(!empty($class_names))
			{
				foreach($class_names as $key=>$class)
				{
					$class=strtolower($class);
					if(!in_array($class,$this->ignore_class_names))
					{
						array_push($this->ignore_class_names,$class);
					}
				}
			}
		}
		else{
			$this->class_names=$class_names;
		}	
		
		
		return $class_names;	
	}		
	
	/*
	 * 产生类名的替换名
	 */
	public function gen_class_names_key($class_names=array())
	{
		$result=array();
		if(!empty($class_names))
		{
			foreach($class_names as $index=>$class_name)
			{
				$class_name=strtolower($class_name);
				if(!class_exists($class_name) && !in_array($class_name,$this->ignore_class_names))//不替换系统保留类
				{
					$key=$this->random_string('lower_letter', $this->class_name_key_lenth);
					while(in_array($key,$result))
					{
						$key=$this->random_string('lower_letter', $this->class_name_key_lenth);
					}
					$result[$class_name]=$key;		
				}
				else{
					$result[$class_name]=$class_name;
				}	
			}
		}
		else{
			if(!empty($this->class_names))
			{
				foreach($this->class_names as $index=>$class_name)
				{
					$class_name=strtolower($class_name);
					if(!class_exists($class_name) && !in_array($class_name,$this->ignore_class_names))//不替换系统保留类
					{
						$key=$this->random_string('lower_letter', $this->class_name_key_lenth);
						while(in_array($key,$result))
						{
							$key=$this->random_string('lower_letter', $this->class_name_key_lenth);
						}
						$result[$class_name]=$key;		
					}
					else{
						$result[$class_name]=$class_name;
					}	
				}
			}
		}
		$this->class_names_key=$result;
		return $result;		
	}	
	
	
	/*
	 * 替换类名和类的构造函数
	 * 替换类名需要解决的问题：
	 * 
	 * 	class a{} --->type1
	 *  class a extends b{} --->type2
	 *  
	 *  class a implements b{} --->type3
	 *  class a implements b,c{}--->type3
	 *  
	 *  interface a{} --->type4
	 *  interface a extends b,c{}--->type5
	 *  
	 *  class a extends b implements c,d{}--->type6
	 *  
	 *  Match::Max()--->type7
	 *  $a=new b()
	 *  $a=new b
	 *  $a instanceof b
	 *  function(a $b)  类型提示
	 *  
	 */
	public function replace_class_names($content)
	{
		/*
		 * class a{}
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(class\s+[a-z_A-Z0-9]+(\s|\r\n)*\{)';//--->type1
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(class|\s|\r\n|\{)/';
			foreach($matches as $key=>$item)
			{
				$new_class_name=strtolower(trim(preg_replace($pattern,'',$item)));
				
				if(isset($this->class_names_key[$new_class_name]))
				{
					$patterns[]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[]='class '.$this->class_names_key[$new_class_name].'{';
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
			}
		}
		
		/*
		 * class a extends b
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(class\s+[a-z_A-Z0-9]+\s+extends\s+[a-z_A-Z0-9]+(\s|\r\n)*\{)';//--->type2
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(class|extends|\r\n|\{)/';
			foreach($matches as $key=>$item)
			{
				$new_class_name=trim(preg_replace($pattern,'',$item));
				
				$new_class_name=explode(' ',$new_class_name);
				
				$new_class_name=$this->cls_array->remove_key($this->cls_array->trim_empty($new_class_name));
				
				$tmp0=strtolower($new_class_name[0]);//转为小写
				$tmp1=strtolower($new_class_name[1]);//转为小写
				
				if(isset($this->class_names_key[$tmp0]) || isset($this->class_names_key[$tmp1]))
				{
					if(isset($this->class_names_key[$tmp0]))
					{
						$class_1=$this->class_names_key[$tmp0];
					}	
					else{
						$class_1=$new_class_name[0];
					}
					
					if(isset($this->class_names_key[$tmp1]))
					{
						$class_2=$this->class_names_key[$tmp1];
					}	
					else{
						$class_2=$new_class_name[1];
					}						
				
					$patterns[]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[]='class '.$class_1.' extends '.$class_2.'{';
				}	

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
				
			}
		}		
		
		/*
		 * class a implements a,b,c
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(class\s+[a-z_A-Z0-9]+\s+implements\s+([a-z_A-Z0-9,\s])+(\s|\r\n)*\{)';//--->type3
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(class|implements|,|\r\n|\{)/';
			foreach($matches as $key=>$item)
			{
				$class_key=array();
				$need_replace=false;
			
				$new_class_name=trim(preg_replace($pattern,' ',$item));
				
				$new_class_name=explode(' ',$new_class_name);
				
				$new_class_name=$this->cls_array->remove_key($this->cls_array->trim_empty($new_class_name));
				
				if(!empty($new_class_name))
				{
					foreach($new_class_name as $k=>$class)
					{
						$tmp=strtolower($class);
						if(isset($this->class_names_key[$tmp]))
						{
							$class_key[$k]=$this->class_names_key[$tmp];
							$need_replace=true;
						}	
						else{
							$class_key[$k]=$class;
						}						
					}
				}
				if($need_replace===true)
				{
					$new_class_string='class ';
					$num_of_key=count($class_key);
					foreach($class_key as $k=>$c_key)
					{
						if($k==0)
						{
							$new_class_string.=$c_key.' implements ';
						}
						else
						{
							if($k==$num_of_key-1)//最后一个
							{
								$new_class_string.=$c_key.'{';
							}
							else{
								$new_class_string.=$c_key.',';
							}
						}
					}
					$patterns[]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[]=$new_class_string;					
					
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
				
			}
		}		

		/*
		 * interface a{}
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(interface\s+[a-z_A-Z0-9]+(\s|\r\n)*\{)';//--->type4
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(interface|\s|\r\n|\{)/';
			foreach($matches as $key=>$item)
			{
				$new_class_name=strtolower(trim(preg_replace($pattern,' ',$item)));
				if(isset($this->class_names_key[$new_class_name]))
				{
					$patterns[]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[]='interface '.$this->class_names_key[$new_class_name].'{';
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
			}
		}
		
		/*
		 * interface a extends b,c,d{}
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(interface\s+[a-z_A-Z0-9]+\s+extends\s+([a-z_A-Z0-9,\s])+(\s|\r\n)*\{)';//--->type5
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(interface|extends|,|\r\n|\{)/';
			foreach($matches as $key=>$item)
			{
				$class_key=array();
				$need_replace=false;
			
				$new_class_name=trim(preg_replace($pattern,' ',$item));
				
				$new_class_name=explode(' ',$new_class_name);
				
				$new_class_name=$this->cls_array->remove_key($this->cls_array->trim_empty($new_class_name));
				
				if(!empty($new_class_name))
				{
					foreach($new_class_name as $k=>$class)
					{
						$tmp=strtolower($class);
						if(isset($this->class_names_key[$tmp]))
						{
							$class_key[$k]=$this->class_names_key[$tmp];
							$need_replace=true;
						}	
						else{
							$class_key[$k]=$class;
						}						
					}
				}
				if($need_replace===true)
				{
					$new_class_string='interface ';
					$num_of_key=count($class_key);
					foreach($class_key as $k=>$c_key)
					{
						if($k==0)
						{
							$new_class_string.=$c_key.' extends ';
						}
						else
						{
							if($k==$num_of_key-1)//最后一个
							{
								$new_class_string.=$c_key.'{';
							}
							else{
								$new_class_string.=$c_key.',';
							}
						}
					}
					$patterns[]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[]=$new_class_string;					
					
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
				
			}
		}	
		
		/*
		 * class a extends b implements c,d,e{}
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(class\s+[a-z_A-Z0-9]+\s+extends\s+([a-z_A-Z0-9])+\s+implements\s+([a-z_A-Z0-9,\s])+(\s|\r\n)*\{)';//--->type6
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(class|extends|implements|,|\r\n|\{)/';
			foreach($matches as $key=>$item)
			{
				$class_key=array();
				$need_replace=false;
			
				$new_class_name=trim(preg_replace($pattern,' ',$item));
				
				$new_class_name=explode(' ',$new_class_name);
				
				$new_class_name=$this->cls_array->remove_key($this->cls_array->trim_empty($new_class_name));
				
				if(!empty($new_class_name))
				{
					foreach($new_class_name as $k=>$class)
					{
						$tmp=strtolower($class);
						if(isset($this->class_names_key[$tmp]))
						{
							$class_key[$k]=$this->class_names_key[$tmp];
							$need_replace=true;
						}	
						else{
							$class_key[$k]=$class;
						}						
					}
				}
				if($need_replace===true)
				{
					$new_class_string='class ';
					$num_of_key=count($class_key);
					foreach($class_key as $k=>$c_key)
					{
						if($k==0)
						{
							$new_class_string.=$c_key.' extends ';
						}
						elseif($k==1)
						{
							$new_class_string.=$c_key.' implements ';
						}
						else
						{
							if($k==$num_of_key-1)//最后一个
							{
								$new_class_string.=$c_key.'{';
							}
							else{
								$new_class_string.=$c_key.',';
							}
						}
					}
					$patterns[]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[]=$new_class_string;					
					
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
				
			}
		}			
		
		
		/*
		 * Match::Max()
		 */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='[a-z_A-Z0-9]+::[a-z_A-Z0-9]+';//--->type7
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			foreach($matches as $key=>$item)
			{
				$class_string=explode('::',$item);
				$new_class_name=strtolower(trim($class_string[0]));
				$other_part=trim($class_string[1]);
				
				if(isset($this->class_names_key[$new_class_name]))
				{
					$patterns[]='/'.'(?<![a-z_A-Z0-9])'.$this->add_slash_for_pattern($item).'/';
					$replacements[]=$this->class_names_key[$new_class_name].'::'.$other_part;
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
			}
		}
		
		
		/*
		 * $a=new b()
		 * 或
		 * $a=new b
		 * */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(?<![a-z_A-Z0-9])new\s+[a-z_A-Z0-9]+';//--->type8
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(new)/';
			foreach($matches as $key=>$item)
			{
				$new_class_name=strtolower(trim(preg_replace($pattern,'',$item)));
				
				if(isset($this->class_names_key[$new_class_name]))
				{
					$patterns[]='/'.'(?<![a-z_A-Z0-9])'.$this->add_slash_for_pattern($item).'(?![a-z_A-Z0-9])/';
					$replacements[]='new '.$this->class_names_key[$new_class_name];
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
			}
		}
		
		/*
		 * $a=instanceof b
		 * */
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(?<![a-z_A-Z0-9])instanceof\s+[a-z_A-Z0-9]+';//--->type8
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern='/(instanceof)/';
			foreach($matches as $key=>$item)
			{
				$new_class_name=strtolower(trim(preg_replace($pattern,'',$item)));
				
				if(isset($this->class_names_key[$new_class_name]))
				{
					$patterns[]='/'.'(?<![a-z_A-Z0-9])'.$this->add_slash_for_pattern($item).'/';
					$replacements[]='instanceof '.$this->class_names_key[$new_class_name];
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
			}
		}

		
		/*
		 * 类型提示
		 * function cal_max(A $var1='',B $var2){}
		 * */
				
		$patterns=array();
		$replacements=array();
		$pattern='/';
		$pattern.='(?<![a-z_A-Z0-9])function\s+[a-z_A-Z0-9]+\s*\(.*\)';//--->type8
		$pattern.='/';

		preg_match_all($pattern,$content,$match);
		$matches=$match[0];
		
		if(!empty($matches))
		{
			$pattern1='/(?<![a-z_A-Z0-9])function\s+[a-z_A-Z0-9]+\s*\(/';
			$pattern2='/\(.*\)/';
			
			foreach($matches as $key=>$item)
			{
				$func_name=trim(preg_replace($pattern2,'',$item));//函数名function a
				$func_name=str_replace('function','',$func_name);
			
				//检查函数名是不是类名，如果是，那么要替换
				//存在的问题：如何区分构造函数和普通函数
				
				$paras=trim(preg_replace($pattern1,'',$item));
				$paras=trim(substr($paras,0,strlen($paras)-1));//去掉后面的括号,即得到函数括号里面的参数部分
				
				if(!empty($paras))
				{
					$paras_array=explode(',',$paras);//获得每个参数
					if(!empty($paras_array))
					{
						foreach($paras_array as $k=>$para_item)
						{
							$para_item=trim($para_item);
							$para_item=explode(' ',$para_item);
							if(count($para_item)>=2)//参数有类型提示
							{
								$tmp=strtolower($para_item[0]);
								
								if(isset($this->class_names_key[$tmp]))
								{
									$para_item[0]=$this->class_names_key[$tmp];//替换类型提示
								}
								
								$paras_array[$k]=implode(' ',$para_item);
							}
						}
						
						$paras=implode(',',$paras_array);
					}
					
					$patterns[]='/'.'(?<![a-z_A-Z0-9])'.$this->add_slash_for_pattern($item).'/';
					$replacements[]='function '.$func_name.'('.$paras.')';
				}
				else{
					continue;
				}

				if(!empty($patterns))
				{
					$content=preg_replace($patterns, $replacements, $content,1);
				}
			}
		}
		

		//Todo:替换构造函数名
		$pattern='/[a-z_A-Z0-9]+\s*\(/';
		preg_match_all($pattern,$content,$match);
		
		$funcs=$match[0];

		if(!empty($funcs))
		{
			$pattern='/(\()|(\s+)/';
			foreach($funcs as $key=>$func)
			{
				$func=strtolower(trim(preg_replace($pattern,'',$func)));
				
				//如果不是系统自带函数,并且不在忽略函数列表里，并且不是类的构造函数
				if(!function_exists($func) && !in_array($func,$this->ignore_functions))
				{
					if(isset($this->class_names_key[$func]))
					{
							$patterns[]='/'.'(?<![a-z_A-Z0-9])'.$this->add_slash_for_pattern($funcs[$key]).'/';
							$replacements[]=$this->class_names_key[$func].'(';		
					}						
				}
			}
			if(!empty($patterns))
			{
				$content=preg_replace($patterns, $replacements, $content,1);
			}	
		}		
		
		
		return $content;
	}
	
	/*
	 * 获得函数名
	 */
	public function get_functions($content,$trim_repeat=true)
	{
		$pattern='/function\s+[a-z_A-Z0-9]+\(.*\)/';
		preg_match_all($pattern,$content,$match);
		
		if(!empty($match[0]))
		{
			if($trim_repeat===true)
			{
				$result=$this->cls_array->trim_repeat($match[0]);
			}
			else{
				$result=$match[0];
			}
		}
		else{
			$result=array();
		}
		
		
		$pattern='/((function\s+)|(\(.*\)))/';
		if(!empty($result))
		{
			foreach($result as $key=>$func)
			{
				$result[$key]=strtolower(trim(preg_replace($pattern,'',$func)));//统一换为小写
			}
		}
		
		return $result;		
	}
	
	/*
	 * 获得所有函数名
	 */	
	public function get_all_functions($path='',$ignore=false)
	{
		if($ignore===false)
		{
			if(empty($path))
			{
				$files=$this->files;
			}
			else{
				$files=$this->get_files($path);
			}
		}
		else{
			$files=parent::get_files($path,$this->file_ext);
			if(!empty($files))	
			{
				foreach($files as $key=>$file)
				{
					if(!in_array($file,$this->ignore_files))
					{
						array_push($this->ignore_files,$file);
					}
				}
			}
		}	

		if(!empty($files))
		{
			foreach($files as $file)
			{
				$content=$this->read_file(dirname($file),basename($file));
				$funcs[]=$this->get_functions($content);
			}
			$funcs=$this->cls_array->flat_array($funcs);
			$funcs=$this->cls_array->trim_repeat($funcs);
			$funcs=$this->cls_array->trim_empty($funcs);
		}
		else{
			$funcs=array();
		}

		if($ignore===true)
		{
			if(!empty($funcs))
			{
				foreach($funcs as $key=>$func)
				{
					$func=strtolower($func);
					if(!in_array($func,$this->ignore_functions))
					{
						array_push($this->ignore_functions,$func);
					}
				}
			}
		}
		else{
			$this->functions=$funcs;
		}		
		
		return $funcs;	
	}	
	

	public function gen_functions_key($funcs=array())
	{
		$result=array();
		if(!empty($funcs))
		{
			foreach($funcs as $index=>$func)
			{
				$func=strtolower($func);
				if(!function_exists($func) && !in_array($func,$this->ignore_functions) && !in_array($func,$this->class_names))//不替换系统保留函数，类保留函数，构造函数
				{
					$key=$this->random_string('lower_letter', $this->function_key_lenth);
					while(in_array($key,$result))
					{
						$key=$this->random_string('lower_letter', $this->variable_key_lenth);
					}
					$result[$func]=$key;	
				}
				else{
					$result[$func]=$func;
				}
			}
		}
		else{
			if(!empty($this->functions))
			{
				foreach($this->functions as $index=>$func)
				{
					$func=strtolower($func);
					if(!function_exists($func) && !in_array($func,$this->ignore_functions) && !in_array($func,$this->class_names))//如果不是系统自带函数
					{
						$key=$this->random_string('lower_letter', $this->function_key_lenth);
						while(in_array($key,$result))
						{
							$key=$this->random_string('lower_letter', $this->variable_key_lenth);
						}
						$result[$func]=$key;	
					}
					else{
						$result[$func]=$func;
					}
				}
			}
		}
		$this->functions_key=$result;
		return $result;		
	}
	
	
	/*
	 * 替换函数名（除构造函数外）
	 */
	public function replace_functions($content)
	{
		$pattern='/[a-z_A-Z0-9]+\s*\(/';
		preg_match_all($pattern,$content,$match);
		
		$funcs=$match[0];

		if(!empty($funcs))
		{
			$pattern='/(\()|(\s+)/';
			foreach($funcs as $key=>$func)
			{
				$func=strtolower(trim(preg_replace($pattern,'',$func)));
				if(isset($this->functions_key[$func]))
				{
						$patterns[]='/'.'(?<![a-z_A-Z0-9])'.$this->add_slash_for_pattern($funcs[$key]).'/';
						$replacements[]=$this->functions_key[$func].'(';		
					}						

			}
							
			if(!empty($patterns))
			{
				$content=preg_replace($patterns, $replacements, $content,1);
			}	
		}
		
		return $content;
	}

	/*
	 * 获取$content里面的所有回调函数，加入到ignore_functions里面。
	 */
	public function get_callback_functions($content)
	{
		foreach($this->callbacks as $key=>$callback)
		{
			$pattern='/';
			$pattern.='(?<![a-z_A-Z0-9])'.$callback.'\s*\(.*\)';
			$pattern.='/';
			
			preg_match_all($pattern,$content,$match);
			
			$full_funcs=$match[0];
			
			if(!empty($full_funcs))
			{
				foreach($full_funcs as $k=>$full_func)
				{				
					if(!in_array($full_func,$this->full_callback_functions))
					{
							array_push($this->full_callback_functions,$full_func);
						}					
					
					$pattern='/(\'[a-z_A-Z0-9]+\')|("[a-z_A-Z0-9]+")/';
					
					preg_match_all($pattern,$full_func,$match);
					
					$callback_funcs=$match[0];
					if(!empty($callback_funcs))
					{
						foreach($callback_funcs as $i=>$callback_func)
						{
							$callback_func=substr($callback_func,1,strlen($callback_func)-1);//去除头部的引号
							$callback_func=substr($callback_func,0,strlen($callback_func)-1);
							if(!in_array($callback_func,$this->callback_functions))
							{
								array_push($this->callback_functions,$callback_func);
								array_push($this->ignore_functions,$callback_func);
							}
						}
					}
				}
			}
		}
	}

	/*
	 * 获取所有回调函数，加入到ignore_functions里面。
	 */	
	public function get_all_callback_functions($path='')
	{
		if(empty($path))
		{
			$files=$this->files;
		}
		else{
			$files=$this->get_files($path);
		}

		if(!empty($files))
		{
			foreach($files as $file)
			{
				$content=$this->read_file(dirname($file),basename($file));
				$this->get_callback_functions($content);
			}
		}
	}
	
	public function get_files($path)
	{
		$this->path=$this->transact_path($path);
		$this->files=parent::get_files($path,$this->file_ext);
		return $this->files;
	}

	public function get_variables($content,$trim_repeat=true)
	{
		$pattern='/\$[a-z_A-Z0-9]+/';
		preg_match_all($pattern,$content,$match);

		if(!empty($match[0]))
		{
			if($trim_repeat===true)
			{
				$result=$this->cls_array->trim_repeat($match[0]);
			}
			else{
				$result=$match[0];
			}
		}
		else{
			$result=array();
		}
		return $result;
	}	
	
	public function get_all_variables($path='',$ignore=false)
	{
		if($ignore===false)
		{
			if(empty($path))
			{
				$files=$this->files;
			}
			else{
				$files=$this->get_files($path);
			}
		}
		else{
			$files=parent::get_files($path,$this->file_ext);
			if(!empty($files))	
			{
				foreach($files as $key=>$file)
				{
					if(!in_array($file,$this->ignore_files))
					{
						array_push($this->ignore_files,$file);
					}
				}
			}
		}
		
		if(!empty($files))
		{
			foreach($files as $file)
			{
				$content=$this->read_file(dirname($file),basename($file));
				$variables[]=$this->get_variables($content);
			}
			$variables=$this->cls_array->flat_array($variables);
			$variables=$this->cls_array->trim_repeat($variables);
			$variables=$this->cls_array->trim_empty($variables);
		}
		else{
			$variables=array();
		}

		if($ignore===true)
		{
			if(!empty($variables))
			{
				foreach($variables as $key=>$var)
				{
					if(!in_array($var,$this->ignore_variables))
					{
						array_push($this->ignore_variables,$var);
					}
				}
			}
		}
		else{
			$this->variables=$variables;
		}
	
		return $variables;
	}
	
	public function gen_variables_key($variables=array())
	{
		$result=array();
		if(!empty($variables))
		{
			foreach($variables as $index=>$item)
			{
				if(!in_array($item,$this->ignore_variables))
				{
					$key='$'.$this->random_string('lower_letter', $this->variable_key_lenth);
					while(in_array($key,$result))
					{
						$key='$'.$this->random_string('lower_letter', $this->variable_key_lenth);
					}
					$result[$item]=$key;
				}
				else{
					$result[$item]=$item;
				}
			}
		}
		else{
			if(!empty($this->variables))
			{
				foreach($this->variables as $index=>$item)
				{
					if(!in_array($item,$this->ignore_variables))
					{						
						$key='$'.$this->random_string('lower_letter', $this->variable_key_lenth);
						while(in_array($key,$result))
						{
							$key='$'.$this->random_string('lower_letter', $this->variable_key_lenth);
						}
						$result[$item]=$key;
					}
					else{
						$result[$item]=$item;
					}
				}
			
			}
		}
		$this->variables_key=$result;
		return $result;
	}

	/*
	 * 替换所有类似$GLOBALS['db']里面的变量
	 */
	public function replace_globals_variables($content)
	{	
		$pattern='/\$GLOBALS\s*\[\s*\'[a-z_A-Z0-9]+\'\s*\]/';
		preg_match_all($pattern,$content,$match);
		
		$globals_variables=$match[0];
		
		if(!empty($globals_variables))
		{
			$pattern='/((\$GLOBALS\s*\[\s*\')|(\'\s*\]))/';
			foreach($globals_variables as $key=>$item)
			{
				$new_item=preg_replace($pattern,'',$item);
				$new_item='$'.$new_item;
				
				if(isset($this->variables_key[$new_item]))
				{
					$new_item=$this->variables_key[$new_item];
					
					$new_item=substr($new_item,1,strlen($new_item)-1);//去除$
					
					$new_item="\$GLOBALS['".$new_item."']";
					
					$patterns[$key]='/'.$this->add_slash_for_pattern($item).'/';
					$replacements[$key]=$new_item;						
				}
			}
			
			if(!empty($patterns))
			{
				$content=preg_replace($patterns, $replacements, $content,1);			
			}
			
		}		

		return $content;
	}	
	
	public function replace_class_members($content)
	{
		//把所有成员函数替换成标签
		$pattern='/((->\s*[a-z_A-Z0-9]+\s*\()|(::\s*[a-z_A-Z0-9]+\s*\())/';
		
		preg_match_all($pattern,$content,$match);
	
		$class_funcs=$match[0];
		
		if(!empty($class_funcs))
		{
			foreach($class_funcs as $key=>$item)
			{
				$funcs_patterns[$key]='/'.$this->add_slash_for_pattern($item).'/';
				$funcs_replacements[$key]='<!-funcs-'.$key.'-funcs-!>';	
			}
			
			if(!empty($funcs_patterns))
			{
				$content=preg_replace($funcs_patterns, $funcs_replacements, $content,1);
			}
	
		}	
		
		//替换普通成员变量
		$member_patterns=array();
		$member_replacements=array();
				
		$pattern='/->\s*[a-z_A-Z0-9]+/';
		preg_match_all($pattern,$content,$match);
		$class_members=$match[0];
		
		//echo "<pre>";
			//print_r($class_members);
		//echo "</pre>";
		
		if(!empty($class_members))
		{
			foreach($class_members as $key=>$member)
			{
				$member_name=substr($member,2,strlen($member)-2);
				
				if(isset($this->variables_key['$'.$member_name]))
				{
					//选出变量子集
					$variables_key=$this->variables_key['$'.$member_name];
					$variables_key=substr($variables_key,1,strlen($variables_key)-1);
					$variables_key='->'.$variables_key;
					
					$member_patterns[$key]='/'.$this->add_slash_for_pattern($member).'(?![a-z_A-Z0-9])/';
					$member_replacements[$key]=$variables_key;						
				}		
			}
			
			if(!empty($member_patterns))
			{
				$content=preg_replace($member_patterns,$member_replacements,$content,1);
			}	
		}
		
		//替换静态成员变量
		$member_patterns=array();
		$member_replacements=array();
				
		$pattern='/::\s*[a-z_A-Z0-9]+/';
		preg_match_all($pattern,$content,$match);
		$class_members=$match[0];
		
		//echo "<pre>";
			//print_r($class_members);
		//echo "</pre>";
		
		if(!empty($class_members))
		{
			foreach($class_members as $key=>$member)
			{
				$member_name=substr($member,2,strlen($member)-2);
				
				if(isset($this->variables_key['$'.$member_name]))
				{
					//选出变量子集
					$variables_key=$this->variables_key['$'.$member_name];
					$variables_key=substr($variables_key,1,strlen($variables_key)-1);
					$variables_key='::'.$variables_key;
					
					$member_patterns[$key]='/'.$this->add_slash_for_pattern($member).'(?![a-z_A-Z0-9])/';
					$member_replacements[$key]=$variables_key;						
				}		
			}
			
			if(!empty($member_patterns))
			{
				$content=preg_replace($member_patterns,$member_replacements,$content,1);
			}

		}
		
			
		//把成员函数标签替换回去
		
		if(!empty($class_funcs))
		{
			foreach($class_funcs as $key=>$item)
			{
				$funcs[$key]=$item;
				$funcs_tags[$key]='/<!-funcs-'.$key.'-funcs-!>/';
				
			}
			
			if(!empty($funcs_tags))
			{
				$content=preg_replace($funcs_tags, $funcs, $content,1);
			}
			
		}
		
		return $content;
	}	
	
	/*
	 * 替换变量
	 */
	public function replace_variable($content)
	{
		$variables=$this->get_variables($content,false);
		
		if(!empty($variables))
		{
			foreach($variables as $key=>$var)
			{
				$patterns[$key]='/'.$this->add_slash_for_pattern($var).'(?![a-z_A-Z0-9])/';//变量之后不能是字母
				
				$replacements[$key]=$this->variables_key[$var];						
			}
			
			if(!empty($patterns))
			{
				$content=preg_replace($patterns,$replacements,$content,1);
			}
	
		}
		return $content;
	}
	
	public function encode($path,$ignore_pathes=array(),$ignore_files=array(),$ignore_functions=array(),$sub_path='')
	{
		if(!empty($sub_path))
		{
			$this->sub_path=$this->transact_path($sub_path);
		}
		
		$path=$this->transact_path($path);
		
		$this->clear_dir($path.$this->sub_path,$this->file_ext);
		
		$this->get_files($path);

		$this->get_all_callback_functions($path);		
	
		if(!empty($ignore_pathes))
		{
			$this->ignore_pathes=$ignore_pathes;
			foreach($ignore_pathes as $key=>$ignore_path)
			{
				$this->get_all_variables($ignore_path,true);	
				$this->get_all_class_names($ignore_path,true);
				$this->get_all_functions($ignore_path,true);
			}
		}
		
		if(!empty($ignore_files))
		{
			foreach($ignore_files as $key=>$file)
			{
				if(!in_array($file,$this->ignore_files))
				{
					array_push($this->ignore_files,$file);
				}
			
				$content=$this->read_file(dirname($file),basename($file));
				$variables=$this->get_variables($content,true);
				$functions=$this->get_functions($content,true);
				$class_names=$this->get_class_names($content,true);
				
				if(!empty($variables))
				{
					foreach($variables as $k=>$var)
					{
						if(!in_array($var,$this->ignore_variables))
						{
							array_push($this->ignore_variables,$var);
						}
					}
				}
				if(!empty($functions))
				{
					foreach($functions as $k=>$func)
					{
						$func=strtolower($func);
						if(!in_array($func,$this->ignore_functions))
						{
							array_push($this->ignore_functions,$func);
						}
					}
				}				
				if(!empty($class_names))
				{
					foreach($class_names as $k=>$class)
					{
						$class=strtolower($class);
						if(!in_array($class,$this->ignore_class_names))
						{
							array_push($this->ignore_class_names,$class);
						}
					}
				}						
			}
		}
		
		if(!empty($ignore_functions))
		{
			foreach($ignore_functions as $key=>$func)
			{
				if(!in_array($func,$this->ignore_functions))
				{
					array_push($this->ignore_functions,$func);
				}				
			}
		}
		
		$this->get_all_variables();
		$this->gen_variables_key();
		
		$this->get_all_class_names();
		$this->gen_class_names_key();		
		
		$this->get_all_functions();
		$this->gen_functions_key();			

		/*
		echo '$this->full_callback_functions';
		echo "<pre>";
			print_r($this->full_callback_functions);
		echo "</pre>";				
		
		echo '$this->callback_functions';
		echo "<pre>";
			print_r($this->callback_functions);
		echo "</pre>";			
		
		echo '$this->variables';
		echo "<pre>";
			print_r($this->variables);
		echo "</pre>";
		
		echo '$this->functions';
		echo "<pre>";
			print_r($this->functions);
		echo "</pre>";
		
		echo '$this->class_names';
		echo "<pre>";
			print_r($this->class_names);
		echo "</pre>";		
		
		echo '$this->ignore_variables';
		echo "<pre>";
			print_r($this->ignore_variables);
		echo "</pre>";			

		echo '$this->ignore_functions';
		echo "<pre>";
			print_r($this->ignore_functions);
		echo "</pre>";	
				
		echo '$this->ignore_class_names';
		echo "<pre>";
			print_r($this->ignore_class_names);
		echo "</pre>";			

		echo '$this->class_names';
		echo "<pre>";
			print_r($this->class_names);
		echo "</pre>";				
		
		echo '$this->variables_key';
		echo "<pre>";
			print_r($this->variables_key);
		echo "</pre>";		
		
		echo '$this->class_names_key';
		echo "<pre>";
			print_r($this->class_names_key);
		echo "</pre>";		

		echo '$this->functions_key';
		echo "<pre>";
			print_r($this->functions_key);
		echo "</pre>";	
		*/

		$this->cls_variable->set_file($path.$this->sub_path,'encrypt.dat');
		$this->cls_variable->add('variables_key',$this->variables_key);
		$this->cls_variable->add('class_names_key',$this->class_names_key);
		$this->cls_variable->add('functions_key',$this->functions_key);
		$this->cls_variable->save_all();
		
		if(!empty($this->files))
		{
			foreach($this->files as $key=>$file)
			{
				$filename=basename($file);
				$dirname=dirname($file).'/';
	
				$content=$this->read_file($dirname,$filename);//读取文件内容
				
				if($dirname==$path)
				{
					$subdir='';
				}
				else{
					$subdir=str_replace($path,'',$dirname);
				}
				$dir=$path.$this->sub_path.$subdir;

				$content=$this->replace_variable($content);
				
				$content=$this->replace_class_members($content);
				
				$content=$this->replace_globals_variables($content);
				
				$content=$this->replace_functions($content);
				
				$content=$this->replace_class_names($content);
				
				//$content=$this->trim_comments($content);
				
				$this->write_file($dir,$filename,$content,'rewrite');//写文件
			}
		}
	}
	
	public function decode($path,$sub_path='')
	{
		
		if(!empty($sub_path))
		{
			$this->sub_path=$this->transact_path($sub_path);
		}
		
		$path=$this->transact_path($path);
		
		$this->clear_dir($path.$this->sub_path,$this->file_ext);
		
		$this->get_files($path);
		
 		$this->cls_variable->set_file($path,'encrypt.dat');
   		$this->cls_variable->load();
		$encrypt_info=$this->cls_variable->get();
   		
		echo "<pre>";
			print_r($encrypt_info);
		echo "</pre>";

		
		$this->variables_key=array_flip($encrypt_info['variables_key']);
		$this->functions_key=array_flip($encrypt_info['functions_key']);
		$this->class_names_key=array_flip($encrypt_info['class_names_key']);
		
		if(!empty($this->files))
		{
			foreach($this->files as $key=>$file)
			{
				$filename=basename($file);
				$dirname=dirname($file).'/';
	
				$content=$this->read_file($dirname,$filename);//读取文件内容
				
				if($dirname==$path)
				{
					$subdir='';
				}
				else{
					$subdir=str_replace($path,'',$dirname);
				}
				$dir=$path.$this->sub_path.$subdir;

				$content=$this->replace_variable($content);
				
				$content=$this->replace_class_members($content);
				
				$content=$this->replace_globals_variables($content);
				
				$content=$this->replace_functions($content);
				
				$content=$this->replace_class_names($content);
				
				//$content=$this->trim_comments($content);
				
				$this->write_file($dir,$filename,$content,'rewrite');//写文件
			}
		}		
	}
}



?>